#include <iostream>
#include <fstream>
#include <sstream>
using std::cout;
using std::endl;
using std::cin;
using std::istream;
using std::ostream;
using std::ifstream;
using std::ofstream;
using std::istringstream;
using std::ostringstream;
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <string>
#include <map>
using std::vector;
using std::map;
using std::unordered_map;
using std::set;
using std::string;
using std::pair;
using std::make_pair;

// 使用unordered_map重写词频统计作业。再比较一下使用map和vector时所花费的时间，体会这几种容器的区别


// map
#if 1
class Dictionary
{
public:
    void Read(ifstream& ifs);
    void outPut(ofstream& ofs);
    bool legalWord(string& word);
private:
    map<string, size_t> _words;
};

void Dictionary::Read(ifstream& ifs){
    string word;

    
    while(ifs >> word){
        if(legalWord(word))
            _words[word]++;
    }
}
#endif


// vector
#if 0
class Dictionary
{
public:
    void Read(ifstream& ifs);
    void outPut(ofstream& ofs);
    bool legalWord(string& word);
    int get_subscript(string& word);
private:
    vector<pair<string, size_t>> _words;
};

void Dictionary::Read(ifstream& ifs){
    string word;
    while(ifs >> word){
        if(legalWord(word)){
            int sub = get_subscript(word);
            if(sub != -1){
                _words[sub].second++;
            }else{
                _words.push_back(make_pair(word, 1));
            }
        }
    }
}

int Dictionary::get_subscript(string& word){
    for(int i = 0; i < _words.size(); ++i){
        if(_words[i].first == word){
            return i;
        }
    }
    return -1;
}
#endif


// unordered_map
#if 0
class Dictionary
{
public:
    void Read(ifstream& ifs);
    void outPut(ofstream& ofs);
    bool legalWord(string& word);
private:
    unordered_map<string, size_t> _words;
};

void Dictionary::Read(ifstream& ifs){
    string word;
    while(ifs >> word){
        if(legalWord(word)){
            _words[word]++;
        }
    }
}

#endif

void Dictionary::outPut(ofstream& ofs){
    for(auto& elem : _words){
        ofs << elem.first << "\t";
        ofs << elem.second <<endl;
    }
}

bool Dictionary::legalWord(string& word){
    for(auto& elem : word){
        if(!isalpha(elem)){return false;}
    }
    return true;
}

int main()
{
    ifstream ifs("The_Holy_Bible.txt");
    Dictionary D;
    D.Read(ifs);
    ofstream ofs("out.txt");
    D.outPut(ofs);

}




